import wx
import socket, sys, threading
from pyDemin import *


class DeminWindow(wx.Panel):
	def __init__(self, parent, ID,Thread_E, Thread_R,l,L,deco,inf):
		wx.Panel.__init__(self,parent,ID)
		self.SetSize(parent.GetClientSize())
		self.L=L
		self.l=l
		self.deco=deco
		self.inf=inf
		self.init_buffer()
		self.Bind(wx.EVT_PAINT,self.OnPaint)
		self.Bind(wx.EVT_LEFT_DOWN,self.OnLeft)
		self.Bind(wx.EVT_RIGHT_DOWN,self.OnRight)
		self.gw=0 #c'est sur le serveur que cette info est stockee, il faut aller la chercher on peut eventuellement updater la valeur du serveur dans cette variable de temps en temps.
		self.nm=0
		self.th_E=Thread_E
		self.th_R=Thread_R
		tx6=wx.TextCtrl(self,1000,"",(60,200),size=(340,20),style=wx.TE_PROCESS_ENTER)
		self.Bind(wx.EVT_TEXT_ENTER,self.envoiM,tx6)

	def envoiM(self,event):
		self.th_E.envoiM(event.GetString())

	def OnLeft(self,evt):
		x,y = evt.GetPosition()
		self.th_E.envoiclikG(x,y)
		
	def OnRight(self,evt):
		x,y = evt.GetPosition()
		self.th_E.envoiclikD(x,y)
	def OnPaint(self,evt):
		dc = wx.BufferedPaintDC(self,self.buffer)
	def init_buffer(self):
		w,h = self.GetClientSize()
		self.buffer = wx.EmptyBitmap(w,h)
		dc = wx.BufferedDC(wx.ClientDC(self),self.buffer)
		self.draw(dc)
	def draw(self,dc):
		dc.Clear()
		dc.SetBrush(wx.Brush("red"))
		dc.SetPen(wx.Pen("black",1))
		k=0
		for i in range(self.l):
			for j in range(self.L):
				if self.deco[i,j]==0:
					dc.SetBrush(wx.Brush("grey"))
					dc.DrawRectangle(i*600/self.l,j*600/self.L,600/self.l,600/self.L)
				elif self.deco[i,j]==1:
					dc.DrawText("%d"%self.inf[i,j],i*600/self.l+11,j*600/self.L+7)
				else:
					dc.SetBrush(wx.Brush("grey"))
					dc.DrawRectangle(i*600/self.l,j*600/self.L,600/self.l,600/self.L)
					dc.SetBrush(wx.Brush("red"))
					dc.DrawLine(i*600/self.l+10,j*600/self.L+20,i*600/self.l+10,j*600/self.L+5)
					dc.DrawRectangle(i*600/self.l+10,j*600/self.L+5,10,7)
					dc.DrawLine(i*600/self.l+8,j*600/self.L+20,i*600/self.l+13,j*600/self.L+20)
					k+=1
		dc.DrawText("Nombre de mines restantes : %d"%(self.nm-k),20,620)
		a=wx.Button(self,-1,"new",(550,600),(50,25))
		self.Bind(wx.EVT_BUTTON,self.new,a)
		b=wx.Button(self,-1,"quit",(550,625),(50,25))
		self.Bind(wx.EVT_BUTTON,self.fermerfenetre,b)

	def fermerfenetre(self,event):
		self.GetParent().Destroy()

	def new(self,event):
		self.gw=0
		self.init_buffer()
		event.GetEventObject().Destroy()
		

class GameFrame(wx.Frame):
	def __init__( self, parent, ID, title, pos=wx.DefaultPosition,size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE):
		wx.Frame.__init__(self, parent, ID, title, pos, size, style)
		self.stateclient=0
		self.nom=""
                self.host=""
                self.port=0
		self.ready=0
		self.SetAutoLayout(True)

        #creation des espaces texte pour l'entree des differents parametres de connexion:

                wx.StaticText(self,4,"nom du joueur",(60,00))
                tx1=wx.TextCtrl(self,1000,"",(60,20),size=(340,20),style=wx.TE_PROCESS_ENTER)
                self.Bind(wx.EVT_TEXT_ENTER,self.getnom,tx1)
		wx.StaticText(self,5,"host",(60,40))
                tx2=wx.TextCtrl(self,2000,"",(60,60),size=(340,20),style=wx.TE_PROCESS_ENTER) #style-> enter pas considere comme un caractere
                self.Bind(wx.EVT_TEXT_ENTER,self.gethost,tx2)
                wx.StaticText(self,6,"port",(60,80))
                tx3=wx.TextCtrl(self,3000,"",(60,100),size=(340,20),style=wx.TE_PROCESS_ENTER)
		self.Bind(wx.EVT_TEXT_ENTER,self.getport,tx3)

		#stt=wx.Button(self,-1,"OK",(100,140),(100,40))
		#self.Bind(wx.EVT_BUTTON,self.ok,stt)
		
		self.CreateStatusBar()#cree la bar du bas de la fenetre
                self.SetStatusText("")
                menubar=wx.MenuBar()
                menu=wx.Menu()
                menu.Append(101,"exit","quitte le programme")
                menubar.Append(menu,"fichier")
                self.SetMenuBar(menubar)
                wx.EVT_MENU(self, 101,  self.TimeToQuit)

		#self.GameWindow = DeminWindow(self,-1)
		#self.GameWindow.init_buffer()

        def TimeToQuit(self, event):
		self.Close(True)#ferme la fenetre

	def getnom(self, event):
		self.nom = event.GetString()
		self.ready+=1
		event.GetEventObject().Destroy()
		wx.StaticText(self,1,self.nom,(60,20))
		if (self.ready==3):
			stt=wx.Button(self,-1,"start research",(100,140),(120,40))
			self.Bind(wx.EVT_BUTTON,self.go,stt)

	def gethost(self, event):
		self.host = event.GetString()
		self.ready+=1
		event.GetEventObject().Destroy()
		wx.StaticText(self,2,self.host,(60,60))
		if (self.ready==3):
			stt=wx.Button(self,-1,"start research",(100,140),(120,40))
			self.Bind(wx.EVT_BUTTON,self.go,stt)

	def getport(self, event):
		self.port = int(event.GetString())
		self.ready+=1
		event.GetEventObject().Destroy()
		wx.StaticText(self,3,str(self.port),(60,100))
		if (self.ready==3):
			stt=wx.Button(self,-1,"start research",(100,140),(120,40))
			self.Bind(wx.EVT_BUTTON,self.go,stt)

#	def ok(self, event):
#		self.nom = tx1.GetString()
#		self.host = tx2.GetString()
#		self.port = tx3.GetString()
#		event.GetEventObject().Destroy()

	def go(self, event):
		self.stateclient=1
		connexion = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		try:
			connexion.connect((self.host,self.port))
			print "Connexion etablie avec le serveur."
			self.ready=4
			self.th_R = ThreadReception(self,connexion)
			self.th_E = ThreadEmission(self,connexion)
			tx4=wx.TextCtrl(self,3000,"",(60,130),size=(340,20),style=wx.TE_PROCESS_ENTER)
			self.Bind(wx.EVT_TEXT_ENTER,self.sendmsg,tx4)
			event.GetEventObject().Destroy()
			
			#self.GameWindow = DeminWindow(self,-1,self.th_E,self.th_R,10,10)
			#self.GameWindow.init_buffer()
						
		except socket.error:
			print "La connexion a echoue."
			#sys.exit()
			tx1=wx.TextCtrl(self,1000,"",(60,20),size=(340,20),style=wx.TE_PROCESS_ENTER)
			self.Bind(wx.EVT_TEXT_ENTER,self.getnom,tx1)	
			tx2=wx.TextCtrl(self,2000,"",(60,60),size=(340,20),style=wx.TE_PROCESS_ENTER) #style-> enter pas considere comme un caractere
			self.Bind(wx.EVT_TEXT_ENTER,self.gethost,tx2)
			tx3=wx.TextCtrl(self,3000,"",(60,100),size=(340,20),style=wx.TE_PROCESS_ENTER)
			self.Bind(wx.EVT_TEXT_ENTER,self.getport,tx3)


	def sendmsg(self,event):
		self.th_E.envoiM(event.GetString())
		event.GetEventObject().Destroy()
		tx4=wx.TextCtrl(self,3000,"",(60,130),size=(340,20),style=wx.TE_PROCESS_ENTER)
		self.Bind(wx.EVT_TEXT_ENTER,self.sendmsg,tx4)
		
class GameApp(wx.App):
	def OnInit(self):
			win = GameFrame(None, -1, "Viva Argentina", size=(600, 650),style = wx.DEFAULT_FRAME_STYLE)
			win.Show(True)
			self.SetTopWindow(win)
			return True


class ThreadReception(threading.Thread): #objet thread gerant la reception des messages
    
    def __init__(self,fenetre,conn):
        threading.Thread.__init__(self)
	self.app=fenetre
	self.connexion= conn


        #self.connexion = conn # ref. du socket de connexion

    def run(self):
        while 1:################################################################### En construction
            msg_recu = self.connexion.recv(1024)
	    msg_recu=msg_recu.split(",")
	    if msg_recu[0]=="M":
		    print "*" + msg_recu[1] + "*"
	    if msg_recu[0]=="G":#qd on recoit la grille et les parametres l et L on les mets dans les parametres de la fenetre qui sera une GameFrame
		    self.app.inf=numpy.reshape(msg_recu[2].split(" "),(msg_recu[1].split(" ")[0],msg_recu[1].split(" ")[1]))
		    self.app.deco=numpy.zeros((msg_recu[1].split(" ")[0],msg_recu[1].split(" ")[1]))
		    self.app.l=msg_recu[1].split(" ")[0]
		    self.app.L=msg_recu[1].split(" ")[1]
            if msg_recu =='' or msg_recu.upper() == "FIN":
                break
        # Le thread <reception> se termine ici.
        # On force la fermeture du thread <emission> :
        th_E._Thread__stop()
        print "Client arrete. Connexion interrompue."
        self.connexion.close()


class ThreadEmission(threading.Thread): #objet thread gerant l'emission des messages
    
    def __init__(self,fenetre,conn):
        threading.Thread.__init__(self)
        self.connexion = conn # ref. du socket de connexion
	self.app = fenetre
	
    #def run(self):
     #   while 1:
      #      msg_emis = raw_input()
       #      self.connexion.send(msg_emis)

    def envoiM(self,a):
	    self.connexion.send("M,"+a)

    def envoiclikD(self,x,y):
	    self.connexion.send("R, %d ,%d"%(int(x),int(y)))

    def envoiclikG(self,x,y):
	    self.connexion.send("L, %d ,%d"%(int(x),int(y)))


# Programme principal - Etablissement de la connexion :
#faire deux main loop, un pour rentrer l'host, le port et le nom du joueur et l'autre pour le jeu
#connexion = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#try:
#    connexion.connect((FrameInit1.host, FrameInit1.port))
#except socket.error:
#    print "La connexion a echoue."
#    sys.exit()
#print "Connexion etablie avec le serveur."

app = GameApp()

#th_E = ThreadEmission(connexion)
#th_R = ThreadReception(connexion)
#th_E.start()
#th_R.start()
app.MainLoop()
